package org.adream.account.service;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.adream.account.dao.AccountCancelDao;
import org.adream.account.dao.AccountMergeDao;
import org.adream.account.dao.AreaDao;
import org.adream.account.dao.IntegralHistoryDao;
import org.adream.account.dao.IntegralTypeDao;
import org.adream.account.dao.LoginDao;
import org.adream.account.dao.RealNameAuthDao;
import org.adream.account.dao.RealNameTmpDao;
import org.adream.account.dao.RoleDao;
import org.adream.account.dao.SchoolDao;
import org.adream.account.dao.TagDao;
import org.adream.account.dao.UserDao;
import org.adream.account.dao.UserDetailDao;
import org.adream.account.dao.UserRoleLinkDao;
import org.adream.account.dao.UserVerifyDao;
import org.adream.account.entity.AccountCancelEntity;
import org.adream.account.entity.AccountMergeEntity;
import org.adream.account.entity.IntegralHistoryEntity;
import org.adream.account.entity.IntegralTypeEntity;
import org.adream.account.entity.RealNameAuthEntity;
import org.adream.account.entity.RealNameTmpEntity;
import org.adream.account.entity.RoleEntity;
import org.adream.account.entity.SchoolEntity;
import org.adream.account.entity.TagEntity;
import org.adream.account.entity.UserDetailEntity;
import org.adream.account.entity.UserEntity;
import org.adream.account.entity.UserVerifyEntity;
import org.adream.account.model.LoginModel;
import org.adream.account.model.ResultModel;
import org.adream.account.model.SynDream2020DataModel;
import org.adream.account.model.UserInfoModel;
import org.adream.account.model.UserIntegralModel;
import org.adream.account.model.UserRoleResModel;
import org.adream.account.rest.api.model.ExcelHead;
import org.adream.account.rest.api.model.FrontBasicInfoForm;
import org.adream.account.rest.api.model.ImportUserIntegral;
import org.adream.account.rest.api.model.RegForm;
import org.adream.account.rest.api.model.UserForm;
import org.adream.account.rest.api.model.UserIntegralLogQueryParams;
import org.adream.account.service.async.SynDream2020Service;
import org.adream.account.service.cloudCollege.SynCloudCollegeService;
import org.adream.account.service.cloudCollege.SynCloudCollegeUserEntity;
import org.adream.account.service.library.SynLibraryService;
import org.adream.account.service.library.SynLibraryUserEntity;
import org.adream.account.service.scfire.SynScFireService;
import org.adream.account.service.scfire.SynScFireUserEntity;
import org.adream.account.util.Constant;
import org.adream.account.util.DateUtils;
import org.adream.account.util.EmojiFilter;
import org.adream.account.util.ExportExcelUtil;
import org.adream.account.util.IdGenerator;
import org.adream.account.util.ImportExcelUtil;
import org.adream.account.util.PasswordUtil;
import org.adream.account.util.QRCodeUtil;
import org.adream.account.util.SensorDataUtil;
import org.adream.account.util.TCPIPUtils;
import org.adream.account.util.UserUtil;
import org.adream.account.util.Utils;
import org.apache.http.Consts;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFDataFormat;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import org.apache.poi.xssf.usermodel.XSSFDataValidationConstraint;
import org.apache.poi.xssf.usermodel.XSSFDataValidationHelper;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;

@Service
public class UserService implements Serializable{
	
	private static final long serialVersionUID = -6642070601926914865L;

	private final static Logger logger = LoggerFactory.getLogger(UserService.class);

	@Autowired
	private UserDao userDao;
	
	@Autowired
	private RealNameTmpDao tmpDao;
	
	@Autowired
	private RoleDao roleDao;

	@Autowired
	private TagDao tagDao;

	@Autowired
	private UserVerifyDao userVerifyDao;

	@Autowired
	private LoginDao loginDao;

	@Autowired
	private HttpSession session;

	@Autowired
	private SchoolDao schoolDao;

	@Autowired
	private SynDream2020Service synDream2020Service;
	
	@Autowired
	private SynScFireService synScFireService;

	@Autowired
	private SynLibraryService synLibraryService;

	@Autowired
	private ValidateService validateService;

	@Autowired
	private UserDetailDao userDetailDao;

	@Autowired
	private RealNameAuthDao realNameAuthDao;

	@Autowired
	private AccountMergeDao accountMergeDao;
	
	@Autowired
	private AccountCancelDao accountCancelDao;
	
	@Autowired
	private UserRoleLinkDao userRoleDao;
	
	@Autowired
	private IntegralHistoryDao integralHistoryDao;
	
	@Autowired
	private IntegralTypeDao integralTypeDao;
	
	@Autowired
	private SynCloudCollegeService synCloudCollegeService;
	
	@Autowired
	private AreaDao areaDao;
	
	@Value("${headimgurl.prefix}")
	private String headimgurlPrefix; // 图片地址前缀
	
	@Value("${cas.logout.url}")
	private String casLogoutUrl;

	@Value("${image.file.path.verifypic}")
	private String verifyPicPath; // 认证图片
	
	//account-新版盒子角色对应map
	private static Map<String, Integer> accountDream2020RoleMap = new HashMap<>();
	
	static {
		accountDream2020RoleMap.put("20181524903016560111", 23);
		accountDream2020RoleMap.put("20181524903016560112", 24);
		accountDream2020RoleMap.put("20181524903016560113", 25);
		accountDream2020RoleMap.put("20181524903016560114", 26);
		accountDream2020RoleMap.put("20181524903016560115", 27);
	}
	
	/**
	 * 根据uid查询user
	 * 
	 * @param uid user id
	 * @return
	 */
	public UserEntity queryUserByUid(String uid) {
		return userDao.queryUserByUid(uid);
	}

	/**
	 * 
	 * @param dr  删除标志
	 * @param uid user id
	 * @return
	 */
	public UserEntity queryUserByDrAndUid(int dr, String uid) {
		return userDao.queryUserByDrAndUid(dr, uid);
	}

	/**
	 * 根据删除标志查询
	 * 
	 * @param dr 删除标志
	 * @return
	 */
	public List<UserEntity> queryUsersByDr(Integer dr) {
		return userDao.queryUsersByDr(dr);
	}

	/**
	 * 通过手机号查询user
	 * 
	 * @param phone 手机号
	 * @return
	 */
	public UserEntity queryUserByPhone(String phone) {
		return userDao.queryUserByPhone(phone);
	}

	/**
	 * 		检查用户名是否已经存在
	 * 
	 * @param uname 用户名
	 * @param uid  若为空，查全部；不为空，查 除了该uid的其他全部
	 * 	
	 * @return
	 */
	public boolean isExistUname(String uname, String uid) {
		if (StringUtils.isEmpty(uname)) {
			return false;
		}
		boolean isExistUname = false;
		int num = userDao.countUserByUname(uname,uid);
		if (num > Constant.ZERO) {
			isExistUname = true;
		}
		return isExistUname;
	}

	/**
	 * 检查手机号是否已注册
	 * 
	 * @param phone 手机号
	 * @return
	 */
	public boolean isExistPhone(String phone) {
		if (StringUtils.isEmpty(phone)) {
			return false;
		}
		boolean isExistPhone = false;
		int num = userDao.countUserByPhone(phone);
		if (num > Constant.ZERO) {
			isExistPhone = true;
		}
		return isExistPhone;
	}

	/**
	 * 检查邮箱是否已绑定
	 * 
	 * @param email 邮箱
	 * @return
	 */
	public boolean isExistEmail(String email) {
		if (StringUtils.isEmpty(email)) {
			return false;
		}
		boolean isExistEmail = false;
		int num = userDao.countUserByEmail(email);
		if (num > Constant.ZERO) {
			isExistEmail = true;
		}
		return isExistEmail;
	}

	/**
	 * 新增user,同时新增login
	 * 
	 * @param userEntity user
	 */
	public ResultModel<String> addUser(UserEntity userEntity) {
		userEntity.setCreator((String) session.getAttribute("uid"));
		userEntity.setCts(new Date());
		userEntity.setModifier((String) session.getAttribute("uid"));
		userEntity.setMts(new Date());
		userEntity.setDr(Constant.ONE);
		int result = userDao.addUser(userEntity);
		if(result == 0) {
			return new ResultModel<String>(ResultModel.ERR_DATABASE, "系统错误,请联系管理员", null);
		}
		return new ResultModel<String>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, null);
	}
	
	/**
	 * 添加用户角色
	 * @param uid
	 * @param rleId
	 * @return
	 */
	public ResultModel<?> replaceUserRoleById(String uid, String rleId) {
		int result = userRoleDao.replaceUserRoleById(uid, rleId);
		if(result == Constant.ZERO) {
			logger.warn("添加用户-角色失败,数据库出错:(");
			return new ResultModel<String>(ResultModel.ERR_DATABASE, "系统错误196,请联系管理员", null);
		}
		//神策数据设置用户属性
		SensorDataUtil.saProfileSet(uid, true, "role_name", userRoleDao.queryRolesByUidAndDr(uid, Constant.ONE) != null
			? userRoleDao.queryRolesByUidAndDr(uid, Constant.ONE).getRleName() : "");
		if(Utils.starRleIdRleNameMap.containsKey(rleId)) {
			SensorDataUtil.saProfileSet(uid, true, "level", Utils.starRleIdRleNameMap.get(rleId));
		}
		
		if(accountDream2020RoleMap.containsKey(rleId)) {			
			//同步新版盒子数据
			SynDream2020DataModel data = new SynDream2020DataModel();
			data.setCasid(uid);
			Map<Integer, Integer> roleIsDelMap = new HashMap<>();
			roleIsDelMap.put(accountDream2020RoleMap.get(rleId), 0);
			data.setRoleIsDelMap(roleIsDelMap);
			synDream2020Service.synDream2020Data(data);
		}
		return new ResultModel<String>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, null);
	}

	/**
	 * 删除user 逻辑删除
	 * @param user
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.DEFAULT)
	public ResultModel<String> deleteUser(UserEntity user) {
		user.setModifier((String) session.getAttribute("uid"));
		user.setMts(new Date());
		user.setDr(Constant.ZERO);
		int result = userDao.deleteUser(user);
		if(result == 0) {
			return new ResultModel<String>(ResultModel.ERR_DATABASE, "系统错误,请联系管理员", null);
		}

		// 删除对应的登录记录
		loginDao.deleteLoginByUid(user.getUid());
		return new ResultModel<String>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, null);
	}
	
	/**
	 * 更新用户手机号
	 * @param form
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.DEFAULT)
	public ResultModel<String> updateUserPhone(UserForm form) {
		if(userDao.queryUserByPhone(form.getPhone()) != null && !form.getUid().equals(userDao.queryUserByPhone(form.getPhone()).getUid())) {
			logger.warn("更新失败,手机号已被占用phone:{}", form.getPhone());
			return new ResultModel<String>(ResultModel.HAS_FOUND_OBJECT, "更新失败,手机号已被占用", null);
		}
		UserEntity user = userDao.queryUserByUid(form.getUid());
		if(user == null) {
			logger.warn("更新失败,未查询到相应的用户uid:{}", form.getUid());
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, "更新失败,用户不存在", null);
		}
		//更改后的phone与之前的不一致
		if(!form.getPhone().equals(user.getPhone())) {
			//原来的phone
			String oriPhone = user.getPhone();
			user.setPhone(form.getPhone());
			user.setModifier(session.getAttribute("uid") == null ? user.getUid() : (String) session.getAttribute("uid"));
			user.setMts(new Date());
			int result = userDao.updateUser(user);
			if(result == 0) {
				return new ResultModel<String>(ResultModel.ERR_DATABASE, "系统错误,请联系系统管理员", null);
			}
			
			//若oriPhone不为空&存在对应的登录方式&登录方式uid与当前uid一致时   更新对应的手机登录方式
			if(!StringUtils.isEmpty(oriPhone)) {
				LoginModel phoneLogin = loginDao.queryLoginByLogin(oriPhone);
				if(phoneLogin != null && form.getUid().equals(phoneLogin.getUid())) {
					phoneLogin.setLogin(form.getPhone());
					loginDao.updateLoginByOriLogin(phoneLogin, oriPhone);
				}
			}
			
			//神策数据设置用户属性 '手机号'
			SensorDataUtil.saProfileSet(form.getUid(), true, "phone_number", form.getPhone());
			
			//同步新版盒子数据
			SynDream2020DataModel data = new SynDream2020DataModel();
			data.setCasid(form.getUid());
			data.setPhone(form.getPhone());
			synDream2020Service.synDream2020Data(data);
		}
		return new ResultModel<String>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, null);
	}
	
	/**
	 * 更新用户邮箱
	 * @param form
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.DEFAULT)
	public ResultModel<String> updateUserEmail(UserForm form) {
		if(userDao.queryUserByEmail(form.getEmail()) != null && !form.getUid().equals(userDao.queryUserByEmail(form.getEmail()).getUid())) {
			logger.warn("更新失败,邮箱已被占用email:{}", form.getEmail());
			return new ResultModel<String>(ResultModel.HAS_FOUND_OBJECT, "更新失败,邮箱已被占用", null);
		}
		UserEntity user = userDao.queryUserByUid(form.getUid());
		if(user == null) {
			logger.warn("更新失败,未查询到相应的用户uid:{}", form.getUid());
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, "更新失败,用户不存在", null);
		}
		//更改后的email与之前的不一致
		if(!form.getEmail().equals(user.getEmail())) {
			//原来的email
			String oriEmail = user.getEmail();
			//更改后的email全部置为小写
			user.setEmail(form.getEmail().toLowerCase());
			user.setModifier(session.getAttribute("uid") == null ? user.getUid() : (String) session.getAttribute("uid"));
			user.setMts(new Date());
			int result = userDao.updateUser(user);
			if(result == 0) {
				return new ResultModel<String>(ResultModel.ERR_DATABASE, "系统错误,请联系系统管理员", null);
			}
			
			//若oriEmail不为空&存在对应的登录方式&登录方式uid与当前uid一致时 更新对应的邮箱登录方式
			if(!StringUtils.isEmpty(oriEmail)) {
				LoginModel emailLogin = loginDao.queryLoginByLogin(oriEmail);
				if(emailLogin != null && form.getUid().equals(emailLogin.getUid())) {
					emailLogin.setLogin(form.getEmail().toLowerCase());
					loginDao.updateLoginByOriLogin(emailLogin, oriEmail);
				}
			}
			
			//神策数据设置用户属性 '邮箱'
			SensorDataUtil.saProfileSet(form.getUid(), true, "mail", form.getEmail());
			
			//同步新版盒子数据
			SynDream2020DataModel data = new SynDream2020DataModel();
			data.setCasid(form.getUid());
			data.setEmail(form.getEmail());
			synDream2020Service.synDream2020Data(data);
		}
		return new ResultModel<String>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, null);
	}
	
	/**
	 * 更新用户信息
	 * @param form
	 * @throws ADreamServiceException
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = ADreamServiceException.class, isolation = Isolation.DEFAULT)
	public ResultModel<String> updateUserLogin(UserForm form) throws ADreamServiceException {
		/**
		 * 查看信息是否已被使用
		 */
		if(!StringUtils.isEmpty(form.getUname()) && userDao.queryUserByUname(form.getUname()) != null && !form.getUid().equals(userDao.queryUserByUname(form.getUname()).getUid())) {
			logger.warn("更新失败,昵称已被占用uname:{}", form.getUname());
			return new ResultModel<String>(ResultModel.HAS_FOUND_OBJECT, "更新失败,昵称已被占用", null);
		}
		if(!StringUtils.isEmpty(form.getPhone()) && userDao.queryUserByPhone(form.getPhone()) != null && !form.getUid().equals(userDao.queryUserByPhone(form.getPhone()).getUid())) {
			logger.warn("更新失败,手机号已被占用phone:{}", form.getPhone());
			return new ResultModel<String>(ResultModel.HAS_FOUND_OBJECT, "更新失败,手机号已被占用", null);
		}
		if(!StringUtils.isEmpty(form.getEmail()) && userDao.queryUserByEmail(form.getEmail()) != null && !form.getUid().equals(userDao.queryUserByEmail(form.getEmail()).getUid())) {
			logger.warn("更新失败,邮箱已被占用email:{}", form.getEmail());
			return new ResultModel<String>(ResultModel.HAS_FOUND_OBJECT, "更新失败,邮箱已被占用", null);
		}
		UserEntity user = userDao.queryUserByUid(form.getUid());
		if(user == null) {
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, "更新失败,用户不存在", null);
		}
		
		//原来的信息
		String oriUname = user.getUname();
		String oriPhone = user.getPhone();
		String oriEmail = user.getEmail();
		
		BeanUtils.copyProperties(form, user);
		user.setModifier(session.getAttribute("uid") == null ? user.getUid() : (String) session.getAttribute("uid"));
		user.setMts(new Date());
		int result = userDao.updateUser(user);
		if(result == 0) {
			return new ResultModel<String>(ResultModel.ERR_DATABASE, "系统错误,请联系系统管理员", null);
		}
		
		//神策数据设置用户属性
		SensorDataUtil.saProfileSet(form.getUid(), true, "phone_number", form.getPhone());
		SensorDataUtil.saProfileSet(form.getUid(), true, "mail", form.getEmail());

		
		//同步新版盒子数据
		SynDream2020DataModel data = new SynDream2020DataModel();
		data.setCasid(form.getUid());
		data.setName(form.getUname());
		data.setPhone(form.getPhone());
		data.setEmail(form.getEmail());
		
		LoginModel login = Utils.isEmptyCollection(loginDao.queryLoginByUid(user.getUid())) ? null
				: loginDao.queryLoginByUid(user.getUid()).get(0);
		//存在登录记录
		if (login != null) {
			//判断原始的uname是否为空
			if(!StringUtils.isEmpty(oriUname)) {
				//判断uname是否包含emoji,若包含,查询将报错
				if(!EmojiFilter.containsEmoji(oriUname)) {				
					LoginModel unameLogin = loginDao.queryLoginByLogin(oriUname);
					if(unameLogin != null && form.getUid().equals(unameLogin.getUid())) {
						loginDao.deleteLoginByLogin(oriUname);
						//uname不为空,直接覆盖uname登录方式
						if(!StringUtils.isEmpty(form.getUname())) {
							login.setLogin(form.getUname());
							loginDao.replaceLogin(login);
						}
					}
				}
			}
			//先删除之前的手机登录方式
			loginDao.deleteLoginByLogin(oriPhone);
			//手机号码不为空,直接覆盖手机登录方式
			if(!StringUtils.isEmpty(form.getPhone())) {
				login.setLogin(form.getPhone());
				loginDao.replaceLogin(login);
			}
			//先删除之前的邮箱登录方式
			loginDao.deleteLoginByLogin(oriEmail);
			//邮箱不为空,直接覆盖邮箱登录方式
			if(!StringUtils.isEmpty(form.getEmail())) {
				login.setLogin(form.getEmail().toLowerCase());
				loginDao.replaceLogin(login);
			}
		}
		
		if (form.getRleIds() != null) { // 更改"用户角色"
			// 更新用户角色信息
			boolean isAdreamBoxAdmin = false;
			boolean isDreamDirector = false;
			if (form.getRleIds().size() == Constant.ZERO) {
				userRoleDao.deleteUserRoleByUidAndVerify(form.getUid(), Constant.ZERO);
			} else {
				//删除user-非认证role
				userRoleDao.deleteUserRoleByUidAndVerify(form.getUid(), Constant.ZERO);
				
				//先删除盒子对应星级角色
				Map<Integer, Integer> roleIsDelMap = new HashMap<>();
				roleIsDelMap.put(Constant.ADREAM_BOX_2020_ONE_STAR_ADREAM_ROLE_ID, 1);
				roleIsDelMap.put(Constant.ADREAM_BOX_2020_TWO_STAR_ADREAM_ROLE_ID, 1);
				roleIsDelMap.put(Constant.ADREAM_BOX_2020_THREE_STAR_ADREAM_ROLE_ID, 1);
				roleIsDelMap.put(Constant.ADREAM_BOX_2020_FOUR_STAR_ADREAM_ROLE_ID, 1);
				roleIsDelMap.put(Constant.ADREAM_BOX_2020_FIVE_STAR_ADREAM_ROLE_ID, 1);
				
				for (String rleId : form.getRleIds()) {
					int count = userRoleDao.replaceUserRoleById(form.getUid(), rleId);
					if (count == Constant.ZERO) {
						logger.warn("更新用户角色出错:)");
						throw new ADreamServiceException("更新用户角色出错");
					}
					
					//变更盒子对应星级角色
					if(accountDream2020RoleMap.containsKey(rleId)) {
						roleIsDelMap.put(accountDream2020RoleMap.get(rleId), 0);
					}
					
					// 判读是否是梦想盒子后台管理员
					if (!isAdreamBoxAdmin) {
						UserRoleResModel userRoleRes = roleDao.queryRleResByRleId(rleId, Constant.ONE);
						if (userRoleRes != null && !StringUtils.isEmpty(userRoleRes.getResIds())
								&& userRoleRes.getResIds().indexOf(Constant.ADREAM_BOX_ADMIN) != -1) {
							isAdreamBoxAdmin = true;
						}
					}
					//判断是否是梦想中心主任
					if(!isDreamDirector && Constant.DREAM_DIRECTOR_ROLE_ID.equals(rleId)) {
						isDreamDirector = true;
					}
				}
				if(isDreamDirector) {
					//查询当前用户是否存在梦想教师认证
					UserVerifyEntity teacherVerify = userVerifyDao.queryVerifyByUidAndRleIdAndDr(form.getUid(), Constant.TEACHER_ROLE_ID, Constant.ONE);
					if(teacherVerify == null || teacherVerify.getState() != Constant.TWO) {
						logger.warn("添加用户'梦想中心主任'角色失败,当前用户还未梦想教师认证成功:(");
						throw new ADreamServiceException("添加用户'梦想中心主任'角色失败,请先进行'梦想教师认证'");
					}
					//查询当前用户所在学校是否已绑定过'梦想中心主任',是:去除其他梦想教师'梦想中心主任'角色
					List<UserEntity> directors = userDao.queryTeacherUsersBySuidAndStateAndRleIdAndDr(teacherVerify.getSchool().getUid(), Constant.TWO, Constant.DREAM_DIRECTOR_ROLE_ID, Constant.ONE);
					//当前用户已添加'梦想中心主任'角色
					if(!Utils.isEmptyCollection(directors) && directors.size() > Constant.ONE) {
						directors.forEach(d -> {
							if(!form.getUid().equals(d.getUid())) {								
								userRoleDao.deleteUserRole(d.getUid(), Constant.DREAM_DIRECTOR_ROLE_ID);
							}
						});
					}
					data.setSchoolNumber(teacherVerify.getSid());
				}
				data.setRoleIsDelMap(roleIsDelMap);
			}
			data.setIsAdreamboxAdmin(isAdreamBoxAdmin);
			data.setIsDreamDirector(isDreamDirector);
			//神策数据 设置 '角色信息'字段
			SensorDataUtil.saProfileSet(form.getUid(), true, "role_name", userRoleDao.queryRolesByUidAndDr(form.getUid(), Constant.ONE) != null ?
				userRoleDao.queryRolesByUidAndDr(form.getUid(), Constant.ONE).getRleName() : "");
		}
		synDream2020Service.synDream2020Data(data);
		return new ResultModel<String>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, null);
	}

	/**
	 * 根据uid查询用户的角色,资源
	 * 
	 * @param uid
	 * @param dr
	 * @return
	 */
	public UserRoleResModel queryUserRoleResByUid(String uid, Integer dr) {
		return userDao.queryUserRoleResByUid(uid, dr);
	}

	/**
	 * 分页查询
	 * 
	 * @param dr       删除标志 不为空
	 * @param uid	   user uid
	 * @param uname    user name %uname%
	 * @param rleId    角色ID
	 * @param order    排序
	 * 
	 * @param pageNo   第几页
	 * @param pageSize 每页显示多少条记录
	 * @return
	 */
	public PageInfo<UserEntity> selectBySomeLike(Integer dr, String uid, String uname, String phone, String email
			,String rleId,String order,Integer pageNo,Integer pageSize,String realName) {
		pageNo = (pageNo == null) ? Constant.ONE : pageNo;
		pageSize = (pageSize == null) ? Constant.TEN : pageSize;
		PageHelper.startPage(pageNo, pageSize);
		List<UserEntity> users = userDao.queryUsersByDrAndSomeLike(dr, uid, uname, phone, email,rleId,order,realName);
		users.forEach(u -> {
			u.setRoles(roleDao.queryRolesByDrAndUid(Constant.ONE, u.getUid()));
		});
		// 封装Page对象 每页显示10条记录
		PageInfo<UserEntity> page = new PageInfo<>(users, Constant.TEN);
		return page;
	}
	
	/**
	 * 管理后台-用户管理-组合分页查询
	 * @param dr
	 * @param rleId
	 * @param info
	 * @param startCts
	 * @param endCts
	 * @param order
	 * @param pageNo
	 * @param pageSize
	 * @return
	 */
	public PageInfo<UserEntity> selectByInfo(Integer dr, String rleId, String info, Date startCts, Date endCts, String order, Integer pageNo, Integer pageSize) {
		PageHelper.startPage(pageNo, pageSize);
		List<UserEntity> users = userDao.queryUsersByDrAndRleIdAndInfo(dr, rleId, info, startCts, endCts, order);
		// 封装Page对象 每页显示10条记录
		PageInfo<UserEntity> page = new PageInfo<>(users, Constant.TEN);
		return page;
	}
	
	/**
	 * 更新基本资料
	 * 
	 * @param user
	 * @return
	 * @throws IOException 
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.DEFAULT)
	public ResultModel<String> updateBasicInfo(FrontBasicInfoForm form) {
		logger.debug("更新基本资料");
		if (form == null || StringUtils.isEmpty(form.getUid())) {
			return new ResultModel<String>(ResultModel.ERR_PARAM, "更新失败,请求参数为空", null);
		}
		UserEntity user = userDao.queryUserByUid(form.getUid());
		if (user == null) {
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, "更新失败,未查询到相应数据", null);
		}
		String oriUname = user.getUname();
		String oriSex = user.getSex();
		// 官方认证修改个人信息,传入的uname为空
		if (StringUtils.isEmpty(form.getUname())) {
			form.setUname(user.getUname());
		}
		BeanUtils.copyProperties(form, user);
		//判断uname是否LIKE '手机用户%'
		if(user.getUname().indexOf(Constant.PREFIX_WECHAT_PHONE_USER_UNAME) == -1) {
			user.setIsChangedUname(Constant.ONE);
		} else {
			user.setIsChangedUname(Constant.ZERO);
		}
		user.setModifier(form.getUid());
		user.setMts(new Date());
		int result = userDao.updateBasicInfo(user);
		if(result == 0) {
			return new ResultModel<String>(ResultModel.ERR_DATABASE, "系统错误,请联系系统管理员", null);
		}
		
		try {
			if ((form.getProvince() != null && form.getProvince() != 0) || (form.getCity() != null && form.getCity() != 0)) {
				// 神策数据设置用户属性 '国家、省、市'
				SensorDataUtil.saProfileSet(form.getUid(), true, "country", "中国");
				if (form.getProvince() != null && form.getProvince() != 0) {
					SensorDataUtil.saProfileSet(form.getUid(), true, "province", areaDao.queryAreaById(form.getProvince()).getTitle());
				}
				if (form.getCity() != null && form.getCity() != 0) {
					SensorDataUtil.saProfileSet(form.getUid(), true, "city", areaDao.queryAreaById(form.getCity()).getTitle());
				}
			}
		} catch (Exception e) {
			logger.error("神策异常...>>> updateBasic");
		}
		//更改后的uname与原来的uname不一致&原来的uname不为空&oriUname不含有emoji&uname不含有emoji
		if(!form.getUname().equals(oriUname) && !StringUtils.isEmpty(oriUname) 
				&& !EmojiFilter.containsEmoji(oriUname)
				&& !EmojiFilter.containsEmoji(form.getUname())) {
			LoginModel unameLogin = loginDao.queryLoginByLogin(oriUname);
			//存在uname登录方式&uname登录方式uid与user的uid一致
			if(unameLogin != null && user.getUid().equals(unameLogin.getUid())) {
				unameLogin.setLogin(form.getUname());
				loginDao.updateLoginByOriLogin(unameLogin, oriUname);
			}
		}

		// 同步新版盒子数据		
		SynDream2020DataModel data = new SynDream2020DataModel();
		data.setCasid(form.getUid());
		data.setName(form.getUname());
		data.setSex(form.getSex().equals(Constant.MALE) ? Constant.ONE : Constant.TWO);
		data.setBio(form.getIntro());
		synDream2020Service.synDream2020Data(data);
		
		//同步火堆数据
		if(!StringUtils.isEmpty(user.getUnionid())) {			
			SynScFireUserEntity scFireUser = new SynScFireUserEntity();
			scFireUser.setUnionid(user.getUnionid());
			scFireUser.setUname(form.getUname());
			scFireUser.setGender(form.getSex());
			synScFireService.synScFireUser(scFireUser);
		
		}
		//同步梦想文库数据
		//当前的uname不为空&当前的uname与原来的uname不同时,执行同步操作
		if(!StringUtils.isEmpty(form.getUname()) && !form.getUname().equals(oriUname)) {
			SynLibraryUserEntity libraryUser = new SynLibraryUserEntity();
			libraryUser.setCasid(form.getUid());
			libraryUser.setUname(oriUname);
			libraryUser.setUsername(form.getUname());
			synLibraryService.synLibraryUser(libraryUser);
			
		}
		//同步真爱云学院
		//当前的uname不为空&当前的uname与原来的uname不同时 或 当前的sex不为空&当前的sex与原来的sex不同时,执行同步操作
		if((!StringUtils.isEmpty(form.getUname()) && !form.getUname().equals(oriUname))
			|| (!StringUtils.isEmpty(form.getSex()) && !form.getSex().equals(oriSex))) {			
			SynCloudCollegeUserEntity cloudCollegeUser = new SynCloudCollegeUserEntity();
			cloudCollegeUser.setCasId(form.getUid());
			cloudCollegeUser.setNickName(form.getUname());
			cloudCollegeUser.setSex(form.getSex());
			synCloudCollegeService.synLibraryUser(cloudCollegeUser);
		}
		return new ResultModel<String>(ResultModel.SUCCESS, "更新成功", null);
	}

	public String queryMaxUid() {
		return userDao.queryMaxUid();
	}

	/**
	 * 查uid之后的1000条数据 ，空值时 前1000条
	 * 
	 * @param uid
	 * @return
	 */
	public ArrayList<HashMap<String, Object>> queryUserListByUid(String uid, String mts) {
		// uid从小到大排序 查uid之后的1000条数据
		// user表 和user_detail表 全部信息
		ArrayList<HashMap<String, Object>> userList = userDao.queryUserListByUid(uid, mts);
		return userList;
	}

	public ArrayList<RoleEntity> queryRoleByUid(String uid) {
		ArrayList<RoleEntity> roleEntityLsit = roleDao.queryRoleByUid(uid);
		return roleEntityLsit;
	}

	public ArrayList<TagEntity> queryTagByUid(String uid) {
		ArrayList<TagEntity> TagEntityLsit = tagDao.queryTagByUid(uid);
		return TagEntityLsit;
	}

	public ArrayList<UserVerifyEntity> queryVerifyByUid(String uid) {
		ArrayList<UserVerifyEntity> userVerifyEntityList = userVerifyDao.queryVerifyByUid(uid);
		return userVerifyEntityList;
	}

	public ArrayList<UserVerifyEntity> queryUserVerifyByMts(String mts) {
		ArrayList<UserVerifyEntity> userVerifyEntityList = userVerifyDao.queryUserVerifyByMts(mts);
		return userVerifyEntityList;
	}

	/**
	 * 处理userList 中 user的属性 headimgurl 加地址
	 * 
	 * @param userList
	 * @param headimgurlPrefix
	 * @param headimgurlSuffix
	 * @return
	 */
	public ArrayList<HashMap<String, Object>> processHeadimgurlOfUserList(ArrayList<HashMap<String, Object>> userList,
			String headimgurlPrefix) {
		for (HashMap<String, Object> map : userList) {
			String uid = (String)map.get("uid");
			if(!StringUtils.isEmpty(uid) && !StringUtils.isEmpty(uid.trim())) {				
				map.put("headimgurl", headimgurlPrefix + uid);
			}
		}
		return userList;
	}

	public Map<String, Object> queryUserInfoByPhone(String phone, String headimgurlPrefix) {
		Map<String, Object> rlt = userDao.queryUserInfoByPhone(phone);
		if (rlt != null && rlt.size() != 0) {
			String uid = (String)rlt.get("uid");
			if(!StringUtils.isEmpty(uid) && !StringUtils.isEmpty(uid.trim())) {
				rlt.put("headimgurl", headimgurlPrefix + uid);
			}
		}
		return rlt;
	}

	public String rejectTeacherVerifyByUid(String uid) {
		if (userDao.rejectTeacherVerifyByUid(uid) == 1) {
			return "驳回成功！";
		} else {
			return "没有需要驳回的数据！";
		}

	}

	public ResultModel<?> getUserResIds(String un, String pd) {
		logger.info("验证用户用户名和密码");
		LoginModel loginModel = loginDao.queryLoginByLogin(un);
		if (loginModel == null) {
			logger.warn("验证出错,未查询到相应的登录信息");
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, ResultModel.NOT_FOUND_OBJECT_MSG, null);
		}
		String salt = loginModel.getSalt();
		String password = loginModel.getPassword();
		if (password != null) {
			if (password.equals(PasswordUtil.generate(pd, salt)) || password.equals(PasswordUtil.generate(salt, pd))
					|| password.equals(PasswordUtil.generate(PasswordUtil.generate(pd, ""), salt))) {
				Map<String, Object> rlt = new HashMap<String, Object>();
				rlt.put("uid", loginModel.getUid());
				rlt.put("resIds", userDao.getUserResIdsByUid(loginModel.getUid()));
				return new ResultModel<Map<String, Object>>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, rlt);
			}
		}
		return new ResultModel<String>(ResultModel.ERR_USER_INFO, "验证出错,密码错误", null);
	}

	/**
	 * 申请梦想中心主任
	 * 
	 * @param sid               school id
	 * @param authorizationCode 授权码
	 * @param request
	 * @return
	 */
	@Transactional(rollbackFor = { ADreamServiceException.class, RuntimeException.class })
	public ResultModel<?> applyDirector(String sid, String authorizationCode, HttpServletRequest request)
			throws ADreamServiceException {
		SchoolEntity schoolEntity = schoolDao.querySchoolBySidAndDr(sid, Constant.ONE);
		if (schoolEntity == null) {
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, ResultModel.NOT_FOUND_OBJECT_MSG, null);
		}
		// 目前梦想中心主任设定只能有1位
		if (schoolEntity.getDirectorNum() > 0) {
			return new ResultModel<String>(ResultModel.ERR_PERMISSION, "该学校梦想中心主任已存在", null);
		}

		// 人数 +1
		schoolEntity.setDirectorNum(schoolEntity.getDirectorNum() + 1);

		if (StringUtils.isEmpty(schoolEntity.getAuthorizationCode())) {
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, "请联系管理员确认授权码是否存在", null);
		}
		if (authorizationCode == null || !authorizationCode.trim().equals(schoolEntity.getAuthorizationCode().trim())) {
			return new ResultModel<String>(ResultModel.ERR_USER_INFO, "授权码错误", null);
		}

		schoolEntity.setUid(UserUtil.getUidByRequest(request));

		if (userRoleDao.replaceUserRoleById(UserUtil.getUidByRequest(request), Constant.DREAM_DIRECTOR_ROLE_ID) == 1
				&& schoolDao.updateDirector(schoolEntity) == 1) {
			// 同步"梦想主任"字段
			SynDream2020DataModel data = new SynDream2020DataModel();
			data.setCasid(UserUtil.getUidByRequest(request));
			data.setIsDreamDirector(true);
			synDream2020Service.synDream2020Data(data);
			return new ResultModel<String>(ResultModel.SUCCESS, "操作成功", null);
		} else {
			// 回滚~
			throw new ADreamServiceException("操作失败");
		}
	}

	/**
	 * 
	 * @param uid
	 * @param pageNo
	 * @param pageSize 不能超过50
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public PageInfo<List<Map<String, Object>>> queryUserVerifyInfo(String uid, Integer pageNo, Integer pageSize, String headimgurlPrefix) {
		pageNo = (pageNo == null) ? Constant.ONE : pageNo;
		pageSize = (pageSize == null) ? Constant.TEN : pageSize;
		if (pageSize > 20) {
			pageSize = 20;
		}
		PageHelper.startPage(pageNo, pageSize);
		List users = userVerifyDao.queryUserVerifyInfo(uid);
		if (!StringUtils.isEmpty(headimgurlPrefix)) {
			for (Object o : users) {
				Map<String, Object> map = (Map<String, Object>) o;
				map.put("headimgurl", headimgurlPrefix + map.get("uid"));
			}
		}
		PageInfo<List<Map<String, Object>>> page = new PageInfo<>(users, pageSize);
		return page;
	}

	/**
	 * 注册或登录
	 * @param refererUrl
	 * @param form
	 * @param request
	 * @return
	 * @throws IOException
	 */
	public ResultModel<?> regAndLogin(String refererUrl,RegForm form, HttpServletRequest request) {
		synchronized(("USER_PHONE_" + form.getPhone()).intern()) {
			return createUserByPhone(refererUrl, form, request);
		}
	}
	
	/**
	 * 通过手机号创建用户 
	 * 	若手机号未注册创建用户;已注册直接返回成功
	 * @param refererUrl 引用地址
	 * @param form 注册表单
	 * @param request
	 * @return
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = ADreamServiceException.class, isolation = Isolation.DEFAULT)
	public ResultModel<?> createUserByPhone(String refererUrl,RegForm form, HttpServletRequest request) {
		logger.info("通过未注册的手机号创建用户");
		if (form == null || StringUtils.isEmpty(form.getPhone()) || StringUtils.isEmpty(form.getCode())) {
			logger.warn("注册登录失败,请求数据为空:(");
			return new ResultModel<String>(ResultModel.ERR_PARAM, "请求参数有误", null);
		}
		if (!Utils.verifyPhone(form.getPhone())) {
			logger.warn("注册登录失败,手机号码格式有误:(");
			return new ResultModel<String>(ResultModel.ERR_PARAM, "手机号码有误", null);
		}
		UserEntity user = new UserEntity();
		String uid = IdGenerator.getGuid();
		
		String msg = validateService.verifyPhoneIdentifyCode(form.getCode(),form.getPhone(), request);
		if (msg != null) {
			logger.warn("注册登录失败,验证码有误:(");
			return new ResultModel<String>(ResultModel.ERR_PARAM, msg, null);
		}

		UserEntity userEntity = userDao.queryUserByPhone(form.getPhone());
		if (userEntity != null) { // 手机号若已注册,直接登录
			logger.info("手机号已注册,直接登录");
			// returnObject 返回uid,用于写入acc_oauth_memory记录
			return new ResultModel<String>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, userEntity.getUid());
		}
		
		// 该手机号未注册,通过手机号创建用户

		user.setUid(uid);
		// uname为 "手机用户" + 手机号后四位
		user.setUname("手机用户" + form.getPhone().substring(form.getPhone().length() - 4));
		user.setPhone(form.getPhone());
		user.setCreator(uid);
		user.setCts(new Date());
		user.setModifier(uid);
		user.setMts(new Date());
		user.setDr(Constant.ONE);
		user.setIp(TCPIPUtils.getClientIp(request));
		//user.setPort(request.getRemotePort());
		try {
			user.setIpInfo(TCPIPUtils.getClientIpInfo(request));
		} catch (Exception e) {
			logger.warn("注册失败,有可能受到了攻击");
			return new ResultModel<String>(ResultModel.ERR_SYS, ResultModel.ERR_SYS_MSG, null);
		}
		
		
		
		//神策数据'盒子_注册结果'事件埋点
		String anonymousId = "";
		Map<String, Object> properties = new HashMap<String, Object>();
		properties.put("is_success", false);
		//获取前端的匿名ID
		Cookie[] cookies = request.getCookies();
		if(cookies != null && cookies.length > 0) {
			for (Cookie cookie : cookies) {
				if (Constant.SENSOR_DATA_COOKIE_KEY.equals(cookie.getName())) {
					String value;
					try {
						value = URLDecoder.decode(cookie.getValue(), "UTF-8");
					} catch (UnsupportedEncodingException e) {
						logger.warn(e.getMessage(), e);
						continue;
					}
					JSONObject data = JSONObject.parseObject(value);
					// 先判断first_id键的值,若无数据,取distinct_id的键值,有数据,取first_id的键值
					anonymousId = StringUtils.isEmpty(data.getString("first_id")) ? data.getString("distinct_id")
							: data.getString("first_id");
					break;
				}
			}
		}
		if (userDao.addUser(user) == Constant.ZERO) {
			logger.warn("注册登录失败,用户添加失败");
			properties.put("failure_reason", "用户添加失败");
			SensorDataUtil.saTrack(anonymousId, false, Constant.SENSOR_DATA_ADREAMBOX_REGISTERATION_RESULT, properties);
			return new ResultModel<String>(ResultModel.ERR_PARAM, "请求参数有误", null);
		}
		//将前端的匿名ID与用户ID关联
		SensorDataUtil.saTrackSignUp(uid, anonymousId);
		properties.put("is_success", true);
		properties.put("failure_reason", "");
		
		Map<String, Object> profileProperties = new HashMap<String, Object>();
		profileProperties.put("phone_number", form.getPhone());
		profileProperties.put("first_visit_source",refererUrl);
		SensorDataUtil.saProfileSetOnce(uid, true, "register_time", new Date());
		SensorDataUtil.saProfileSetOnce(uid, true, "register_source", refererUrl);
		SensorDataUtil.saProfileSetOnce(uid, true, "adreambox_id", uid);
		SensorDataUtil.saProfileSet(uid, true, profileProperties);
		SensorDataUtil.saTrack(uid, true, Constant.SENSOR_DATA_ADREAMBOX_REGISTERATION_RESULT, properties);
		// returnObject 返回uid,用于写入acc_oauth_memory
		return new ResultModel<String>(ResultModel.SUCCESS, "注册成功", uid);
	}

	public ResultModel<?> getResIds(String uid) {
		Map<String, Object> rlt = new HashMap<String, Object>();
		rlt.put("resIds", userDao.getUserResIdsByUid(uid));
		return new ResultModel<Map<String, Object>>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, rlt);
	}

	/**
	 * 用户注册
	 * 
	 * @param form    注册表单
	 * @param request
	 * @return
	 * @throws IOException 
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = ADreamServiceException.class, isolation = Isolation.DEFAULT)
	public ResultModel<?> reg(String refererUrl,RegForm form, HttpServletRequest request) {
		logger.info("用户注册");
		//神策数据'盒子_注册结果'事件埋点
		String anonymousId = "";
		Map<String, Object> properties = new HashMap<String, Object>();
		properties.put("is_success", false);
		//获取前端的匿名ID
		Cookie[] cookies = request.getCookies();
		if(cookies != null && cookies.length > 0) {
		     for (Cookie cookie : cookies){
		        if(Constant.SENSOR_DATA_COOKIE_KEY.equals(cookie.getName())) {
		        	String value ;
		        	try {
						value = URLDecoder.decode(cookie.getValue(), "UTF-8");
					} catch (UnsupportedEncodingException e) {
						logger.warn(e.getMessage(), e);
						continue;
					}
		        	JSONObject data = JSONObject.parseObject(value);
		        	//先判断first_id键的值,若无数据,取distinct_id的键值,有数据,取first_id的键值
		        	anonymousId = StringUtils.isEmpty(data.getString("first_id")) ? data.getString("distinct_id") : data.getString("first_id");
		        	break;
		        }
		     }
		 }   
		if (form == null || StringUtils.isEmpty(form.getPhone()) || StringUtils.isEmpty(form.getPassword())
				|| StringUtils.isEmpty(form.getCode())) {
			logger.warn("注册失败,请求参数为空:(");
			properties.put("failure_reason", "信息不完整");
			SensorDataUtil.saTrack(anonymousId, false, Constant.SENSOR_DATA_ADREAMBOX_REGISTERATION_RESULT, properties);
			return new ResultModel<String>(ResultModel.ERR_PARAM, "注册失败,请填写完整信息", null);
		}
		if (!Utils.verifyPhone(form.getPhone())) {
			logger.warn("注册失败,手机号码格式有误:(" + form.getPhone());
			properties.put("failure_reason", "手机号码格式有误");
			SensorDataUtil.saTrack(anonymousId, false, Constant.SENSOR_DATA_ADREAMBOX_REGISTERATION_RESULT, properties);
			return new ResultModel<String>(ResultModel.WARN_PHONE, ResultModel.WARN_PHONE_MSG, null);
		}
		UserEntity userEntity = userDao.queryUserByPhone(form.getPhone());
		LoginModel loginModel = loginDao.queryLoginByLogin(form.getPhone());
		
		UserEntity user = new UserEntity();
		String uid = IdGenerator.getGuid();
		synchronized ("USER_PHONE_" + form.getPhone()) {
			if (userEntity != null || loginModel != null) {
				logger.warn("注册失败,该手机号已注册:(");
				properties.put("failure_reason", "该手机号已注册");
				SensorDataUtil.saTrack(anonymousId, false, Constant.SENSOR_DATA_ADREAMBOX_REGISTERATION_RESULT, properties);
				return new ResultModel<String>(ResultModel.WARN_PHONE, "该手机号已注册,请直接登录", null);
			}
			String msg = validateService.verifyPhoneIdentifyCode(form.getCode(), form.getPhone(), request);
			if (msg != null) {
				logger.warn("注册失败,验证码输入有误:(");
				properties.put("failure_reason", msg);
				SensorDataUtil.saTrack(anonymousId, false, Constant.SENSOR_DATA_ADREAMBOX_REGISTERATION_RESULT, properties);
				return new ResultModel<String>(ResultModel.WARN_CHECKCODE, msg, null);
			}

			user.setUid(uid);
			user.setPhone(form.getPhone());
			user.setUname("手机用户" + user.getPhone().substring(user.getPhone().length() - 4, user.getPhone().length()));
			user.setCreator(uid);
			user.setCts(new Date());
			user.setModifier(uid);
			user.setMts(new Date());
			user.setDr(Constant.ONE);
			user.setIp(TCPIPUtils.getClientIp(request));
			//user.setPort(request.getRemotePort());
			try {
				user.setIpInfo(TCPIPUtils.getClientIpInfo(request));
			} catch (Exception e) {
				logger.warn("注册失败,有可能受到了攻击");
				properties.put("failure_reason", "注册失败,有可能受到了攻击");
				SensorDataUtil.saTrack(anonymousId, false, Constant.SENSOR_DATA_ADREAMBOX_REGISTERATION_RESULT, properties);
				return new ResultModel<String>(ResultModel.ERR_SYS, ResultModel.ERR_SYS_MSG, null);
			}
			
			if (userDao.addUser(user) == Constant.ZERO) {
				logger.warn("注册失败,用户添加失败");
				properties.put("failure_reason", "用户添加失败");
				SensorDataUtil.saTrack(anonymousId, false, Constant.SENSOR_DATA_ADREAMBOX_REGISTERATION_RESULT, properties);
				return new ResultModel<String>(ResultModel.ERR_DATABASE, "注册失败,用户添加失败", null);
			}

			// 添加login
			LoginModel login = new LoginModel();
			login.setUid(uid);
			String salt = Utils.getSixUuid();
			login.setSalt(salt);
			login.setPassword(PasswordUtil.generate(form.getPassword(), salt));
			login.setLogin(form.getPhone());
			login.setMethod(Constant.APWD);
			if (loginDao.addLogin(login) == Constant.ZERO) {
				logger.warn("注册失败,登录记录添加失败:(");
				properties.put("failure_reason", "登录记录添加失败");
				SensorDataUtil.saTrack(anonymousId, false, Constant.SENSOR_DATA_ADREAMBOX_REGISTERATION_RESULT, properties);
				return new ResultModel<String>(ResultModel.ERR_DATABASE, "注册失败,登录信息添加失败", null);
			}
		}
		//将前端的匿名ID与用户ID关联
		SensorDataUtil.saTrackSignUp(uid, anonymousId);
		properties.put("is_success", true);
		properties.put("failure_reason", "");
		//用户表属性-手机设置
		//phone_number 手机号
		//register_time 注册时间
		//register_source 注册来源项目
		//first_visit_source 首次访问来源
		Map<String, Object> profileProperties = new HashMap<String, Object>();
		profileProperties.put("phone_number", form.getPhone());
		profileProperties.put("first_visit_source",refererUrl);
		SensorDataUtil.saProfileSetOnce(uid, true, "register_time", new Date());
		SensorDataUtil.saProfileSetOnce(uid, true, "register_source", refererUrl);
		SensorDataUtil.saProfileSet(uid, true, profileProperties);
		SensorDataUtil.saTrack(uid, true, Constant.SENSOR_DATA_ADREAMBOX_REGISTERATION_RESULT, properties);
		return new ResultModel<String>(ResultModel.SUCCESS, "注册成功", null);
	}

	public RealNameAuthEntity queryRealName(String uid) {
		return realNameAuthDao.queryAuthByUidAndDr(uid, 1);
	}

	/**
	 * 微信是否已绑定
	 * 
	 * @param unionid 微信unionid
	 * @return
	 */
	public boolean isValidUnionid(String unionid) {
		if (StringUtils.isEmpty(unionid)) {
			return false;
		}
		if (userDao.countUserByUnionid(unionid) == Constant.ZERO) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 
	 * @param uid       主账号uid
	 * @param mergerUid 被合并的uid
	 * @param request
	 * @return
	 */
	public ResultModel<?> mergeApplication(String otherUid, String choose, HttpServletRequest request) {
		String uid = UserUtil.getUidByRequest(request);
		AccountMergeEntity accountMergeEntity = accountMergeDao.selectMyMerge(uid, false);
		if(accountMergeEntity !=null) {
			return new ResultModel<String>(ResultModel.ERR_PARAM, "当前账号合并申请处理中！", null);
		}
		List<String> uidRleIds = userDao.getUserRoleIdsByUid(otherUid);
		//角色不为空&&梦想中心学校账号
		if(!Utils.isEmptyCollection(uidRleIds) && uidRleIds.contains(Constant.DREAM_SCHOOL_ROLE_ID)) {
			return new ResultModel<String>(ResultModel.ERR_PARAM, "学校账号,不能合并", null);
		}
		//查询需被合并的用户角色
		List<String> otherUidRleIds = userDao.getUserRoleIdsByUid(otherUid);
		//角色不为空&&梦想中心学校账号
		if(!Utils.isEmptyCollection(otherUidRleIds) && otherUidRleIds.contains(Constant.DREAM_SCHOOL_ROLE_ID)) {
			return new ResultModel<String>(ResultModel.ERR_PARAM, "学校账号,不能合并", null);
		}
		String mergeUid = otherUid;
		switch (choose) {
		case "my":
			break;
		case "other":
			String p = uid;
			uid = mergeUid;
			mergeUid = p;
			break;
		default:
			return new ResultModel<String>(ResultModel.ERR_SERVICE, "申请失败！", null);
		}
		if (accountMergeDao.insertMergeInfo(uid, mergeUid) == 1) {
			return new ResultModel<String>(ResultModel.SUCCESS, "申请成功", null);
		} else {
			return new ResultModel<String>(ResultModel.ERR_SERVICE, "申请失败", null);
		}

	}

	public ResultModel<?> queryMergeInfo(String uid) {
		//uid相关的  未处理的合并申请
		AccountMergeEntity accountMergeEntity = accountMergeDao.selectLastMergeByUid(uid);
		if(accountMergeEntity==null) {
			//代码2001
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, "第一次合并", null);
		} else {
			String rString = "";
			if(accountMergeEntity.getIsProcessed()!=null&&accountMergeEntity.getIsProcessed()==0) {
				UserEntity userEntity = null;
				if(accountMergeEntity.getUid()!=null&&uid.equals(accountMergeEntity.getUid())) {
					userEntity = userDao.queryUserByUid(accountMergeEntity.getMergeUid());
				}else {
					userEntity = userDao.queryUserByUid(accountMergeEntity.getUid());
				}
				if(userEntity !=null) {
					rString = StringUtils.isEmpty(userEntity.getUname())||StringUtils.isEmpty(userEntity.getUname().trim())?"":userEntity.getUname(); 
				} 
			}
			accountMergeEntity.setUid(null);
			accountMergeEntity.setMergeUid(null);
			accountMergeEntity.setMergeUsername(rString);
			return new ResultModel<AccountMergeEntity>(ResultModel.SUCCESS, "已申请", accountMergeEntity);
		}
	}
	
	/**
	 * 账户注销申请
	 * @param accountCancel
	 * @return
	 */
	public ResultModel<?> cancelApplication(AccountCancelEntity accountCancel) {
		//查询需被注销的用户角色
		List<String> cancelUidRleIds = userDao.getUserRoleIdsByUid(accountCancel.getCancelUid());
		//角色不为空&&梦想中心学校账号
		if(!Utils.isEmptyCollection(cancelUidRleIds) && cancelUidRleIds.contains(Constant.DREAM_SCHOOL_ROLE_ID)) {
			return new ResultModel<String>(ResultModel.ERR_PARAM, "学校账号,不能合并", null);
		}
		accountCancel.setState(Constant.ONE);
		accountCancel.setCts(new Date());
		accountCancel.setMts(new Date());
		accountCancel.setDr(Constant.ONE);
		int result = accountCancelDao.replaceCancelInfo(accountCancel);
		if(result == Constant.ZERO) {
			logger.warn("注销申请失败,系统错误");
			return new ResultModel<String>(ResultModel.ERR_DATABASE, "系统错误527,请联系管理员", null);
		}
		return new ResultModel<String>(ResultModel.SUCCESS, "注销申请成功", null);
	}
	
	/**
	 * 查询注销信息
	 * @param uid
	 * @return
	 */
	public ResultModel<?> queryCancelInfo(String uid) {
		AccountCancelEntity accountCancel = accountCancelDao.queryRecentCancelByUid(uid);
		if(accountCancel == null) {
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, "未提交过注销申请", null);
		}
		String uname = "";
		if(accountCancel.getState() != null && accountCancel.getState() == Constant.ONE) {
			UserEntity userEntity = userDao.queryUserByUid(accountCancel.getCancelUid());
			if(userEntity !=null) {
				uname = StringUtils.isEmpty(userEntity.getUname())||StringUtils.isEmpty(userEntity.getUname().trim())?"":userEntity.getUname(); 
			} 
		}
		accountCancel.setUid(null);
		accountCancel.setCancelUid(null);
		accountCancel.setCancelUname(uname);
		return new ResultModel<AccountCancelEntity>(ResultModel.SUCCESS, "已提交过注销申请", accountCancel);
	}
	
	//清空用户缓存
	public ResultModel<?> flushUserCache(String uid) {
		UserEntity user = userDao.queryUserByUid(uid);
		if(user == null) {
			logger.warn("清除用户缓存失败,用户不存在:(");
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, "清空失败,数据不存在", null);
		}
		user.setMts(new Date());
		int result = userDao.updateUserMts(user);
		if(result == Constant.ZERO) {
			logger.warn("清除用户缓存失败,内部错误:(");
			return new ResultModel<String>(ResultModel.ERR_DATABASE, "清空失败,请联系管理员", null);
		}
		return new ResultModel<String>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, null);
	}

	/**
	 * 弃用的 （不知道有没有地方用到 先保留）
	 * @param unionid
	 * @param request
	 * @return
	 */
	public ResultModel<?> queryUserInfoByUnionid(String unionid, HttpServletRequest request) {
		if(StringUtils.isEmpty(unionid)||StringUtils.isEmpty(unionid.trim())) {
			return new ResultModel<String>(ResultModel.ERR_PARAM, ResultModel.ERR_PARAM_MSG, null);
		}
		Map<String, Object> rlt = new HashMap<String,Object>();
		UserEntity userEntity = userDao.searchByUnionid(unionid);
		if(userEntity == null) {
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, ResultModel.NOT_FOUND_OBJECT_MSG, null);
		}
		rlt.put("userEntity", userEntity);
		
		RealNameAuthEntity realNameAuthEntity = realNameAuthDao.queryAuthByUidAndDr(userEntity.getUid(), 1);
		//实名通过的返回
		if(realNameAuthEntity!=null&&realNameAuthEntity.getState()!=null&&realNameAuthEntity.getState()==2) {
			rlt.put("realNameAuthEntity", realNameAuthEntity);
		}else {
			rlt.put("realNameAuthEntity", null);
		}
		
		List<UserVerifyEntity> userVerifyList = userVerifyDao.queryDetailByUidAndDr(userEntity.getUid(), 1);
		rlt.put("userVerifyList", userVerifyList);
		
		return new ResultModel<Map<String, Object>>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, rlt);
	}
	
	/**
	 * 查询用户基本信息,角色,权限,认证信息
	 * @param uid
	 * @return
	 */
	public ResultModel<?> queryUserInfo(String uid) {
		Integer dr = Constant.ONE;
		UserInfoModel userInfo = userDao.queryUserInfo(uid, dr);
		if(userInfo == null) {
			logger.warn("未查询到相应数据");
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, "查询失败,数据未存在", null);
		}
		//性别
		if(!StringUtils.isEmpty(userInfo.getSex()) && Constant.MALE.equals(userInfo.getSex())) {
			userInfo.setSex(Constant.MALE_CN);
		}
		userInfo.setHeadimgurl(headimgurlPrefix + uid);
		RealNameAuthEntity realNameAuth = realNameAuthDao.queryAuthByUidAndDr(uid, Constant.ONE);
		if(realNameAuth != null) {
			//不需要返回的清空掉
			realNameAuth.setCreType(null);
			realNameAuth.setCreNum(null);
			realNameAuth.setCreFrontPic(null);
			realNameAuth.setCreReversePic(null);
			
			userInfo.setRealName(realNameAuth.getRealName());
		}
		userInfo.setRealNameAuth(realNameAuth);
		List<UserVerifyEntity> verifies = userVerifyDao.queryDetailVerifiesByUidAndDr(uid, dr);
		if(!Utils.isEmptyCollection(verifies)) {
			verifies.forEach(v -> {
				RealNameTmpEntity realNameTmp = v.getRealNameTmp();
				//不需要返回的清空掉
				realNameTmp.setCreType(null);
				realNameTmp.setCreNum(null);
				realNameTmp.setCreFrontPic(null);
				realNameTmp.setCreReversePic(null);
			});
		}
		userInfo.setVerifies(verifies);
		return new ResultModel<UserInfoModel>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, userInfo);
	}
	
	/**
	 * 查询梦想教师用户信息
	 * @param uids
	 * @return
	 */
	public ResultModel<?> queryTeacherUserInfos(String[] uids) {
		List<UserInfoModel> userInfos = userDao.queryTeacherUserInfos(uids, Constant.ONE);
		if(Utils.isEmptyCollection(userInfos)) {
			logger.warn("未查询到相应数据");
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, "查询失败,数据未存在", null);
		}
		Map<String, UserInfoModel> uidTeacherUserInfoMap = new HashMap<>();
		userInfos.forEach(u -> {
			//处理数据
			uidTeacherUserInfoMap.put(u.getUid(), u);
		});
		return new ResultModel<Map<String, UserInfoModel>>(ResultModel.SUCCESS, "查询成功", uidTeacherUserInfoMap);
	}
	
	public ResultModel<?> queryUserInfos(String[] uids) {
		List<UserInfoModel> userInfos = userDao.queryUserInfos(uids);
		if(Utils.isEmptyCollection(userInfos)) {
			logger.warn("未查询到相应数据");
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, "查询失败,数据未存在", null);
		}
		Map<String, UserInfoModel> uidUserInfoMap = new HashMap<>();
		userInfos.forEach(u -> {
			//处理数据
			uidUserInfoMap.put(u.getUid(), u);
		});
		return new ResultModel<Map<String, UserInfoModel>>(ResultModel.SUCCESS, "查询成功", uidUserInfoMap);
	}

	public ResultModel<?> getRoleIds(String uid) {
		List<String> rlt = userDao.getUserRoleIdsByUid(uid);
		return new ResultModel<List<String>>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, rlt);
	}

	public ResultModel<?> changeBlackList(String uid, boolean isBlack) {
		UserEntity userEntity = userDao.queryUserByUid(uid);
		if(userEntity == null) {
			return new ResultModel<List<String>>(ResultModel.ERR_PARAM, "操作失败，未找到对应用户信息", null);
		}
		String isBlackString = userEntity.getIsBlack();
		if(StringUtils.isEmpty(isBlackString)||StringUtils.isEmpty(isBlackString.trim())) {
			return new ResultModel<List<String>>(ResultModel.ERR_PARAM, "操作失败，用户信息错误", null);
		}
		//最终需要拉黑还是解禁值 默认解禁
		Boolean blackFlag = false;
		if (isBlack) {
			//黑名单的 取消黑名单
			if("0".equals(isBlackString.trim())) {
				return new ResultModel<List<String>>(ResultModel.SUCCESS, "用户已解禁！", null);
			}else {
				blackFlag = false;
			}
		}else {
			//正常用户  加入黑名单
			
			if("1".equals(isBlackString.trim())) {
				return new ResultModel<List<String>>(ResultModel.SUCCESS, "用户已禁用！", null);
			}else {
				blackFlag = true;
			}
		}
		//相反
		//userEntity.setIsBlack(isBlack?"0":"1");
		userDao.updateBlackList(uid,blackFlag);
		
		//cas踢出
		try {
			if(blackFlag) {
				casLogout(casLogoutUrl,uid);
			}
		} catch (Exception e) {
			logger.error("uid:"+uid+"踢下线失败！");
			e.printStackTrace();
		}
		
		return new ResultModel<List<String>>(ResultModel.SUCCESS,blackFlag?"用户已禁用！":"用户已解禁！", null);
	}
	
	private void casLogout(String casLogoutUrl,String uid) throws ClientProtocolException, IOException{
		CloseableHttpClient closeHttpClient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(casLogoutUrl);
		List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("blackUid", uid));
		httpPost.setEntity(new UrlEncodedFormEntity(params, Consts.UTF_8));
		closeHttpClient.execute(httpPost);
	}
	/**
	 * 返回3种角色信息  公益团队，企业，社会组织
	 * @param unionid
	 * @param rleId
	 * @param request
	 * @return
	 */
	public ResultModel<?> getUserInfoByUnionid(String unionid,String rleId, HttpServletRequest request) {
		UserEntity userEntity = userDao.searchByUnionid(unionid);
		if(userEntity == null) {
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, "unionid没有对应用户", "");
		}
		
		//String userVerifyPicPath = verifyPicPath.endsWith(File.separator + "") ? verifyPicPath : (verifyPicPath + File.separator); 
		
		
		UserEntity userModel = new UserEntity();
		userModel.setUid(userEntity.getUid());
		userModel.setUname(userEntity.getUname()==null?"":userEntity.getUname());
		userModel.setPhone(userEntity.getPhone());
		userModel.setNickName(userEntity.getNickName()==null?"":userEntity.getNickName());
		
		/*List<String> roleIds = new ArrayList<String>();
		roleIds.add(Constant.BUSINESS_ROLE_ID);
		roleIds.add(Constant.ORG_ROLE_ID);
		roleIds.add(Constant.PUBLIC_WELFARE_TEAM_ROLE_ID);
		
		int other = userVerifyDao.queryCountNotInRoleIds(userEntity.getUid(), roleIds);
		if(other >0) {
			return new ResultModel<String>(ResultModel.ERR_USER_INFO, "该用户其他身份认证中或已认证", "role");
		}*/
		
		switch (rleId.trim()) {
		case Constant.BUSINESS_ROLE_ID: //企业
		case Constant.ORG_ROLE_ID:  //社会组织
		case Constant.PUBLIC_WELFARE_TEAM_ROLE_ID:  //公益团队
			break;
		default:
			return new ResultModel<String>(ResultModel.ERR_PARAM, "rleId非法", null); 
		}
		UserVerifyEntity userVerify = userVerifyDao.queryVerifyByUidAndRleId(userEntity.getUid(), rleId);
		
		if(userVerify !=null) {
			if(userVerify.getContact()==null) {
				userVerify.setContact("");
			}
			if(userVerify.getPhone()==null) {
				userVerify.setPhone("");
			}
			if(userVerify.getCompany()==null) {
				userVerify.setCompany("");
			}
			if(userVerify.getCreCode()==null) {
				userVerify.setCreCode("");
			}
			if(userVerify.getIntro()==null) {
				userVerify.setIntro("");
			}
			if(userVerify.getCrePic()==null) {
				userVerify.setCrePic("");
			}
			
//			try {
//				userVerify.setCrePic(Utils.ImageToBase64(userVerifyPicPath+userVerify.getCrePic()));
//			} catch (Exception e) {
//				userVerify.setCrePic("");
//				logger.debug("营业证转base64出错");
//			}
		}
		
		RealNameAuthEntity realNameAuthEntity = realNameAuthDao.queryAuthByUidAndDr(userEntity.getUid(),1);
		Integer realAuthState = 0; //0:不存在
		if(realNameAuthEntity !=null) {
			realAuthState = realNameAuthEntity.getState()==null?0:realNameAuthEntity.getState();
		}
		RealNameTmpEntity tmpEntity = tmpDao.queryTmpByUidAndDr(userEntity.getUid(), 1);
		if(tmpEntity != null) {
				if(tmpEntity.getRealName()==null) {
					tmpEntity.setRealName("");
				}
				if(tmpEntity.getCreNum() == null) {
					tmpEntity.setCreNum("");
				}
				if(tmpEntity.getCreFrontPic() == null) {
					tmpEntity.setCreFrontPic("");
				}
				if(tmpEntity.getCreReversePic() == null) {
					tmpEntity.setCreReversePic("");
				}
				tmpEntity.setRealAuthState(realAuthState);
		}	
		
//			try {
//				tmpEntity.setCreFrontPic(Utils.ImageToBase64(userVerifyPicPath+tmpEntity.getCreFrontPic()));
//			} catch (Exception e) {
//				tmpEntity.setCreFrontPic("");
//				logger.debug("用户身份证正面转base64出错");
//			}
//			try {
//				tmpEntity.setCreReversePic(Utils.ImageToBase64(userVerifyPicPath+tmpEntity.getCreReversePic()));
//			} catch (Exception e) {
//				tmpEntity.setCreReversePic("");
//				logger.debug("用户身份证背面转base64出错");
//			}
		UserDetailEntity userDetailEntity = userDetailDao.queryUserDetailByDrAndUid(1,userEntity.getUid());
		if(userDetailEntity!=null) {
			if(userDetailEntity.getAccountName()==null) {
				userDetailEntity.setAccountName("");
			}
			if(userDetailEntity.getBankAccount()==null) {
				userDetailEntity.setBankAccount("");
			}
			if(userDetailEntity.getDepositBank()==null) {
				userDetailEntity.setDepositBank("");
			}
			if(userDetailEntity.getAopenBranch()==null) {
				userDetailEntity.setAopenBranch("");
			}
		}
		
		
		Map<String, Object> rlt = new HashMap<String,Object>();
		rlt.put("userEntity", userModel);
		rlt.put("tmpEntity", tmpEntity==null?"":tmpEntity);
		rlt.put("userVerify", userVerify==null?"":userVerify);
		rlt.put("userDetail", userDetailEntity==null?"":userDetailEntity);
		
		return new ResultModel<Map<String, Object>>(ResultModel.SUCCESS, "操作成功", rlt);
	}

	public ResultModel<?> getUserInfoAndBindUnionidByPhone(String phone,String unionid,String rleId, HttpServletRequest request) {
		UserEntity weChatUser = userDao.searchByUnionid(unionid);
		if(weChatUser !=null) {
			return new ResultModel<String>(ResultModel.ERR_SYS, "业务逻辑错误,微信用户已存在不该调用此接口了", "unionid");
		}
		
		UserEntity phoneUser = userDao.queryUserEntityByPhone(phone);
		
		if (phoneUser == null) {
			//创建新用户
			phoneUser = new UserEntity();
			String uid = IdGenerator.getGuid();
			phoneUser.setUid(uid);
			phoneUser.setUnionid(unionid);
			phoneUser.setPhone(phone);
			phoneUser.setCreator("huodui");
			phoneUser.setCts(new Date());
			phoneUser.setDr(Constant.ONE);
			phoneUser.setModifier("huodui");
			phoneUser.setMts(new Date());
			phoneUser.setUname("手机用户" + phone.substring(phone.length() - 4));
			phoneUser.setIp(TCPIPUtils.getClientIp(request));
			//phoneUser.setPort(request.getRemotePort());
			try {
				phoneUser.setIpInfo(TCPIPUtils.getClientIp(request));
			} catch (Exception e) {
				logger.warn("注册失败,有可能受到了攻击");
				return new ResultModel<String>(ResultModel.ERR_SYS, ResultModel.ERR_SYS_MSG, null);
			}
			
			userDao.addUser(phoneUser);
		} else {
			//绑定微信
			phoneUser.setUnionid(unionid);
			phoneUser.setModifier("huodui");
			phoneUser.setMts(new Date());
			userDao.updateUser(phoneUser);
			
		}
		
		//String userVerifyPicPath = verifyPicPath.endsWith(File.separator + "") ? verifyPicPath : (verifyPicPath + File.separator); 
		
		UserEntity userModel = new UserEntity();
		userModel.setUid(phoneUser.getUid());
		userModel.setUname(phoneUser.getUname());
		userModel.setPhone(phoneUser.getPhone());
		userModel.setNickName(phoneUser.getNickName());
		
		/*List<String> roleIds = new ArrayList<String>();
		roleIds.add(Constant.BUSINESS_ROLE_ID);
		roleIds.add(Constant.ORG_ROLE_ID);
		roleIds.add(Constant.PUBLIC_WELFARE_TEAM_ROLE_ID);
		
		int other = userVerifyDao.queryCountNotInRoleIds(phoneUser.getUid(), roleIds);
		if(other >0) {
			return new ResultModel<String>(ResultModel.ERR_USER_INFO, "该用户其他身份认证中或已认证", "role");
		}*/
		
		switch (rleId.trim()) {
		case Constant.BUSINESS_ROLE_ID: //企业
		case Constant.ORG_ROLE_ID:  //社会组织
		case Constant.PUBLIC_WELFARE_TEAM_ROLE_ID:  //公益团队
			break;
		default:
			return new ResultModel<String>(ResultModel.ERR_PARAM, "rleId非法", null); 
		}
		UserVerifyEntity userVerify = userVerifyDao.queryVerifyByUidAndRleId(phoneUser.getUid(), rleId);
		
		if(userVerify !=null) {
			if(userVerify.getContact()==null) {
				userVerify.setContact("");
			}
			if(userVerify.getPhone()==null) {
				userVerify.setPhone("");
			}
			if(userVerify.getCompany()==null) {
				userVerify.setCompany("");
			}
			if(userVerify.getCreCode()==null) {
				userVerify.setCreCode("");
			}
			if(userVerify.getIntro()==null) {
				userVerify.setIntro("");
			}
			if(userVerify.getCrePic()==null) {
				userVerify.setCrePic("");
			}
			 
//			try {
//				userVerify.setCrePic(Utils.ImageToBase64(userVerifyPicPath+userVerify.getCrePic()));
//			} catch (Exception e) {
//				userVerify.setCrePic("");
//				logger.debug("营业证转base64出错");
//			}
		}
		RealNameAuthEntity realNameAuthEntity = realNameAuthDao.queryAuthByUidAndDr(phoneUser.getUid(),1);
		Integer realAuthState = 0; //0:不存在
		if(realNameAuthEntity !=null) {
			realAuthState = realNameAuthEntity.getState()==null?0:realNameAuthEntity.getState();
		}
		RealNameTmpEntity tmpEntity = tmpDao.queryTmpByUidAndDr(phoneUser.getUid(), 1);
		if(tmpEntity != null) {
				if(tmpEntity.getRealName()==null) {
					tmpEntity.setRealName("");
				}
				if(tmpEntity.getCreNum() == null) {
					tmpEntity.setCreNum("");
				}
				if(tmpEntity.getCreFrontPic() == null) {
					tmpEntity.setCreFrontPic("");
				}
				if(tmpEntity.getCreReversePic() == null) {
					tmpEntity.setCreReversePic("");
				}
				tmpEntity.setRealAuthState(realAuthState);
//			try {
//				tmpEntity.setCreFrontPic(Utils.ImageToBase64(userVerifyPicPath+tmpEntity.getCreFrontPic()));
//			} catch (Exception e) {
//				tmpEntity.setCreFrontPic("");
//				logger.debug("用户身份证正面转base64出错");
//			}
//			try {
//				tmpEntity.setCreReversePic(Utils.ImageToBase64(userVerifyPicPath+tmpEntity.getCreReversePic()));
//			} catch (Exception e) {
//				tmpEntity.setCreReversePic("");
//				logger.debug("用户身份证背面转base64出错");
//			}
		}
		
		UserDetailEntity userDetailEntity = userDetailDao.queryUserDetailByDrAndUid(1,phoneUser.getUid());
		if(userDetailEntity!=null) {
			if(userDetailEntity.getAccountName()==null) {
				userDetailEntity.setAccountName("");
			}
			if(userDetailEntity.getBankAccount()==null) {
				userDetailEntity.setBankAccount("");
			}
			if(userDetailEntity.getDepositBank()==null) {
				userDetailEntity.setDepositBank("");
			}
			if(userDetailEntity.getAopenBranch()==null) {
				userDetailEntity.setAopenBranch("");
			}
		}
		Map<String, Object> rlt = new HashMap<String,Object>();
		rlt.put("userEntity", userModel);
		rlt.put("tmpEntity", tmpEntity);
		rlt.put("userVerify", userVerify);
		rlt.put("userDetail", userDetailEntity);
		
		return new ResultModel<Map<String, Object>>(ResultModel.SUCCESS, "操作成功", rlt);
		 
	}
	/**
	 * 检查手机号是否被unionid以外的人占用
	 */
	public Boolean checkPhoneNotUsedByUnionid(String unionid, String phone) {
		if(userDao.countUserByPhoneAndNotUsedByUnionid(unionid,phone) > 0) {
			return false;
		}
		return true;
	}

	public Integer updateUserPhoneByUnionid(String unionid, String phone) {
		UserEntity userEntity =  userDao.searchByUnionid(unionid);
		if(userEntity == null) {
			return null;
		}
		return userDao.updatePhoneByUid(userEntity.getUid(), phone);
	}
	
	/**
	 * 
  	 * @param realName 真实姓名 (模糊搜索)( 非必填，默认为没有 )
	 * @param schoolName 学校名称 (模糊搜索)( 非必填，默认为没有 )
	 * @param phone 手机号  ( 非必填，默认为没有 ) 
	 * @param rleId 角色ID  ( 非必填，默认为没有 ) 
	 * @param page 第几页   ( 非必填，默认为0，第一页为0 )
	 * @param count 最多返回条数( 非必填，默认为20 )
	 * @param areaId 地区ID ( 可以是省市区任意 )
	 * @return
	 */
	public PageInfo<Map<String, Object>> queryUserList(String realName,String schoolName,String phone,
			String rleId,String page,String count,String areaId) {
		if(StringUtils.isEmpty(realName)||StringUtils.isEmpty(realName.trim())) {
			realName = null;
		}
		if(StringUtils.isEmpty(schoolName)||StringUtils.isEmpty(schoolName.trim())) {
			schoolName = null;
		}
		if(StringUtils.isEmpty(phone)||StringUtils.isEmpty(phone.trim())) {
			phone = null;
		}
		if(StringUtils.isEmpty(rleId)||StringUtils.isEmpty(rleId.trim())) {
			rleId = null;
		}
		if(!Utils.isInteger(areaId)||areaId.length()!=6) {
			areaId = null;
		}
		if(!Utils.isInteger(page)) {
			page = null;
		}
		if(!Utils.isInteger(count)) {
			count = null;
		}
		//处理省市区
		String province = null;
		String city = null;
		String area = null;
		if(areaId !=null) {
			int areaIdNum = Integer.parseInt(areaId);
			if(areaIdNum%10000 == 0) {
				province = areaId;
			}else if(areaIdNum % 100 == 0){
				city = areaId;
			}else {
				area = areaId;
			}
		}
		
		int pageNo = 1;
		if(page != null) {
			pageNo = Integer.parseInt(page);
		}
		if(pageNo<1) {
			pageNo = 1;
		}
		
		int pageSize = 20;
		if(count != null) {
			pageSize = Integer.parseInt(count);
		}
		if(pageSize<10 || pageSize>100) {
			pageSize = 20;
		}
		PageHelper.startPage(pageNo,pageSize);
		List<Map<String, Object>> list = userDao.queryUserList(realName,schoolName,phone,
				rleId,province,city,area);
		PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(list,pageSize);
		return pageInfo;
	}

	
	@Value("${image.file.path.userpic}")
	private String userPicPath; // 用户图片
	
	
	public void getUserQRCode(HttpServletRequest req,HttpServletResponse response) throws Exception {
		response.setContentType("image/png");
		ServletOutputStream sops = response.getOutputStream();
		String userString = "https://account.adream.org/account/normal/pages/member/menu.html?contentUrl=idAuthentication.html&creType=6";
//		InputStream ism;
		
		String uid = UserUtil.getUidByRequest(req);
		if(StringUtils.isEmpty(uid)) {
			return;
		}
		UserEntity userEntity  = userDao.queryUserByUid(uid);
		if(userEntity == null) {
			return;
		}
		String qrString =userEntity.getQr();
		if(StringUtils.isEmpty(qrString)||StringUtils.isEmpty(qrString.trim())){
			boolean flag = true;
			while (flag) {
				qrString = Utils.getQrCode();
				if(userDao.selectCountByQr(qrString)==0) {
					flag = false;
				}
			}
			if(userDao.updateQr(userEntity.getUid(),qrString) != 1) {
				return;
			}
		} 
		
		userString = userString + "&qr=" + qrString;
		 
		String ava = userEntity.getHeadimgurl();
		
		String path = null;
		if (StringUtils.isEmpty(ava)||StringUtils.isEmpty(ava.trim())) {
			
//			ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
//			ism = classLoader.getResourceAsStream("dream.png");
		} else {
			
			path = userPicPath.endsWith(File.separator + "") ? userPicPath : userPicPath + File.separator;
			path = path + ava.trim();
//			try {
//				ism = new FileInputStream(path);
//			} catch (Exception e) {
//				ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
//				ism = classLoader.getResourceAsStream("dream.png");
//			}
		}
		
		
		QRCodeUtil.encode(userString, path, "" , true ,sops); 
//		ZXingUtil.getLogoQRCode(userString, ism, "我的二维码标识", sops);
		sops.close();
		
		return;
	}

	public PageInfo<UserEntity> getUserInfoByNameOrPhone(String where, Integer pageNo) {
		if(pageNo == null || pageNo < 1) {
			pageNo = 0;
		}
		int pageSize = 100;
		
		if(StringUtils.isEmpty(where) || StringUtils.isEmpty(where.trim())) {
			return new PageInfo<>(null,pageSize);
		}
		
		PageHelper.startPage(pageNo,pageSize);
		List<UserEntity> list = userDao.getUserInfoByNameOrPhone(where);
		PageInfo<UserEntity> pageInfo = new PageInfo<>(list,pageSize);
		return pageInfo;
	}
	
	/**
	 * 分页查询
	 * @param uid
	 * @param uname
	 * @param phone
	 * @param sname
	 * @param rleIds
	 * @param dr
	 * @param pageNo
	 * @param pageSize
	 * @return
	 */
	public PageInfo<UserIntegralModel> queryUserIntegralsBySomeFields(String uid, String uname, String realName, 
			String phone,String sname, List<String> rleIds, Integer dr, Integer pageNo, Integer pageSize) {
		pageSize = (pageSize != null && pageSize > 0) ? pageSize : 10;
		pageNo = (pageNo == null || pageNo <= 0) ? 1 : (pageNo / pageSize) + 1;
		PageHelper.startPage(pageNo,pageSize);
		List<UserIntegralModel> userIntegrals = userDao.queryUserIntegrals(uid, uname, realName, phone, sname, rleIds, dr);
		if(!Utils.isEmptyCollection(userIntegrals)) {
			userIntegrals.forEach(u -> {
				// 判断是否是'梦想中心'角色
				if(Constant.DREAM_SCHOOL_ROLE_ID.equals(u.getRleIds())) {
					// 设置学校相关属性
					SchoolEntity school = schoolDao.querySchoolByUidAndDr(u.getUid(), Constant.ONE);
					if(school != null) {
						u.setSid(school.getSid());
						u.setSname(school.getSname());
					} else {
						u.setSid("");
						u.setSname("");
					}
				}
			});
		}
		PageInfo<UserIntegralModel> pageInfo = new PageInfo<>(userIntegrals, pageSize);
		return pageInfo;
	}
	
	public PageInfo<UserIntegralModel> queryUserIntegralLogs(String uid, String uname, String realName, 
			String sname, List<String> rleIds,List<String> types,String startTime,String endTime, Integer pageNo, Integer pageSize) {
		pageSize = (pageSize != null && pageSize > 0) ? pageSize : 10;
		pageNo = (pageNo == null || pageNo <= 0) ? 1 : (pageNo / pageSize) + 1;
		PageHelper.startPage(pageNo,pageSize);
		List<UserIntegralModel> userIntegralLogs = userDao.queryUserIntegralLogs(uid, uname, realName, sname, rleIds,types,startTime,endTime);
		if(!Utils.isEmptyCollection(userIntegralLogs)) {
			userIntegralLogs.forEach(u -> {
				// 判断是否是'梦想中心'角色
				if(Constant.DREAM_SCHOOL_ROLE_ID.equals(u.getRleIds())) {
					// 设置学校相关属性
					SchoolEntity school = schoolDao.querySchoolByUidAndDr(u.getUid(), Constant.ONE);
					if(school != null) {
						u.setSid(school.getSid());
						u.setSname(school.getSname());
					} else {
						u.setSid("");
						u.setSname("");
					}
				}
			});
		}
		PageInfo<UserIntegralModel> pageInfo = new PageInfo<>(userIntegralLogs, pageSize);
		return pageInfo;
	}
	/**
	 * 根据uid,dr查询用户积分相关信息
	 * @param uid
	 * @param dr
	 * @return
	 */
	public ResultModel<?> queryUserIntergralByUidAndDr(String uid, Integer dr) {
		UserIntegralModel userIntegralModel = userDao.queryUserIntergralByUidAndDr(uid, dr);
		if(userIntegralModel == null) {
			logger.warn("查询错误,用户不存在:(");
			return new ResultModel<String>(ResultModel.NOT_FOUND_OBJECT, "查询失败,数据不存在", null);
		}
		return new ResultModel<UserIntegralModel>(ResultModel.SUCCESS, "查询成功", userIntegralModel);
	}
	
	/**
	 * 更新用户积分数
	 * 用户积分数正负数 controller层检查判断
	 * @param userIntegralModel
	 * @return
	 */
	public ResultModel<?> updateUserIntegral(UserIntegralModel userIntegralModel) {
		UserEntity user = userDao.queryUserByDrAndUid(Constant.ONE,userIntegralModel.getUid());
		if(user == null) {
			logger.warn("用户积分更新失败,用户不存在:(");
			return new ResultModel<String>(ResultModel.ERR_PARAM, "更新失败,用户不存在", null);
		}
		//比较后台传入的积分数是否与数据库积分数一致,只比对数据大小
		if(userIntegralModel.getIntegral() == null) {
			if(user.getIntegral() != null) {
				logger.warn("积分数不一致,数据库积分数:" + user.getIntegral() + "页面积分数:" + userIntegralModel.getIntegral());
				return new ResultModel<String>(ResultModel.ERR_PARAM, "当前积分数已被更改,请刷新页面重试", null);
			}
		} else {
			if(!userIntegralModel.getIntegral().equals(user.getIntegral())) {
				logger.warn("积分数不一致,数据库积分数:" + user.getIntegral() + "页面积分数:" + userIntegralModel.getIntegral());
				return new ResultModel<String>(ResultModel.ERR_PARAM, "当前积分数已被更改,请刷新页面重试", null);
			}
		}
		int oldIntegral = userIntegralModel.getIntegral() == null ? 0 : userIntegralModel.getIntegral();
		String operator = session.getAttribute("uid") == null ? user.getUid() : (String) session.getAttribute("uid");
		user.setModifier(operator);
		user.setIntegral(oldIntegral + userIntegralModel.getIncreaseIntegral());
		int result = userDao.updateUserIntegralByUid(user);
		if(result == Constant.ZERO) {
			logger.warn("用户积分更新失败,数据库错误:(");
			return new ResultModel<String>(ResultModel.ERR_DATABASE, "系统错误101,请联系系统管理员", null);
		}
		//添加一条积分历史变更数据
		IntegralHistoryEntity integralHistory = new IntegralHistoryEntity();
		integralHistory.setIhid(IdGenerator.getGuid());
		integralHistory.setUid(userIntegralModel.getUid());
		integralHistory.setOldIntegral(oldIntegral);
		integralHistory.setNewIntegral(oldIntegral + userIntegralModel.getIncreaseIntegral());
		integralHistory.setIncreaseIntegral(userIntegralModel.getIncreaseIntegral());
		integralHistory.setItid(userIntegralModel.getItid());
		integralHistory.setComment(userIntegralModel.getComment());
		integralHistory.setCreator(operator);
		integralHistory.setModifier(operator);
		integralHistory.setDr(Constant.ONE);
		int addIntegralHistoryResult = integralHistoryDao.addIntegralHistory(integralHistory);
		if(addIntegralHistoryResult == Constant.ZERO) {
			logger.warn("积分明细新增失败,数据库错误:(");
			return new ResultModel<String>(ResultModel.ERR_DATABASE, "系统错误102,请联系系统管理员", null);
		}
		return new ResultModel<String>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, null);
	}
	
	/**
	 * 导出批量增减积分模板
	 * @param response
	 */
	public void exportUpdateUserIntegralsExcel(HttpServletResponse response) {
		XSSFWorkbook workBook = new XSSFWorkbook();
		XSSFSheet sheet = workBook.createSheet();
		// 设置页名称
		workBook.setSheetName(0, "批量增减积分模板");
		// 设置title样式
		XSSFCellStyle titleStyle = workBook.createCellStyle();
		titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		titleStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
		// 创建表头行
		XSSFRow row = sheet.createRow(0);
		// 插入Excel表头
		XSSFCell uidCell = row.createCell(0);
		sheet.setColumnWidth(0, 5500);
		uidCell.setCellValue("uid");

		XSSFCell typeCell = row.createCell(1);
		typeCell.setCellValue("增减类型");
		XSSFCell integralCell = row.createCell(2);
		integralCell.setCellValue("积分数");
		XSSFCell itNameCell = row.createCell(3);
		sheet.setColumnWidth(0, 4000);
		itNameCell.setCellValue("变动类型");
		XSSFCell commentCell = row.createCell(4);
		commentCell.setCellValue("内容");
		
		// 设置CELL格式为文本格式
		XSSFCellStyle stringStyle = workBook.createCellStyle();
		XSSFDataFormat format = workBook.createDataFormat();
		stringStyle.setDataFormat(format.getFormat("@"));
		// 单独设置uid这一列格式都为文本 暂时先手动设置
//		for (int i = 1; i < 10000; i++) {
//			XSSFRow xssfRow = sheet.createRow(i);
//			XSSFCell uidDataCell = xssfRow.createCell(0);
//			uidDataCell.setCellStyle(stringStyle);
//		}

		// 增减类型下拉列表
		CellRangeAddressList typeList = null;
		XSSFDataValidation dataValidation = null;

		// 增减类型
		String[] textList = new String[] { "增加", "减少"};
		XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);
		XSSFDataValidationConstraint dvConstraint1 = (XSSFDataValidationConstraint) dvHelper
				.createExplicitListConstraint(textList);

		// 操作类型下拉 首行，末行，首列，末列
		typeList = new CellRangeAddressList(1, 65536, 1, 1);
		dataValidation = (XSSFDataValidation) dvHelper.createValidation(dvConstraint1, typeList);
		// 07默认setSuppressDropDownArrow(true);
		dataValidation.setSuppressDropDownArrow(true);
		dataValidation.setShowErrorBox(true);
		sheet.addValidationData(dataValidation);
		
		List<IntegralTypeEntity> integralTypes = integralTypeDao.queryIntegralTypesByDr(Constant.ONE);
		if(!Utils.isEmptyCollection(integralTypes)) {			
			//变动类型下拉列表
			CellRangeAddressList itNameList = null;
			XSSFDataValidation itNameDataValidation = null;
			String[] itNameTextList = new String[integralTypes.size()];
			int integralTypesSize = integralTypes.size();
			for (int i = 0; i < integralTypesSize; i++) {
				itNameTextList[i] = integralTypes.get(i).getName();
			}
			XSSFDataValidationHelper itNameDvHelper = new XSSFDataValidationHelper(sheet);
			XSSFDataValidationConstraint itNameDvConstraint1 = (XSSFDataValidationConstraint) itNameDvHelper
					.createExplicitListConstraint(itNameTextList);
			// 操作类型下拉 首行，末行，首列，末列
			itNameList = new CellRangeAddressList(1, 65536, 3, 3);
			itNameDataValidation = (XSSFDataValidation) dvHelper.createValidation(itNameDvConstraint1, itNameList);
			// 07默认setSuppressDropDownArrow(true);
			itNameDataValidation.setSuppressDropDownArrow(true);
			itNameDataValidation.setShowErrorBox(true);
			sheet.addValidationData(itNameDataValidation);
		}
		
		// 将文件输出
		// 设置response头信息
		response.reset();
		response.setContentType("application/vnd.ms-excel"); // 改成输出excel文件
		try {
			response.setHeader("Content-disposition", "attachment;filename=" + new String("批量增减积分模板".getBytes("UTF-8"), "ISO-8859-1") + ".xlsx");
		} catch (UnsupportedEncodingException e1) {
			logger.info(e1.getMessage());
		}
		OutputStream out = null;
		try {
			// 将文件输出
			out = response.getOutputStream();
			workBook.write(out);
			out.flush();
		} catch (Exception e) {
			logger.error("导出Excel失败:" + e.getMessage());
			return;
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					logger.warn("导出Excel失败:" + e.getMessage());
					return;
				}
			}
			if(workBook != null) {
				try {
					workBook.close();
				} catch (IOException e) {
					logger.warn("导出Excel失败:" + e.getMessage());
					return;
				}
			}
		}
	}
	/**
	 * 导出用户积分流水
	 * @param response
	 * @throws Exception 
	 */
	public void exportUpdateUserIntegralLogsExcel(UserIntegralLogQueryParams queryParams,HttpServletResponse response) throws Exception {
		List<UserIntegralModel> userIntegralLogs = userDao.queryUserIntegralLogs(queryParams.getUid(), queryParams.getUname(), null, 
				queryParams.getSname(), queryParams.getRleIds(),queryParams.getIntegralTypes(),queryParams.getStartTime(),queryParams.getEndTime());
		if(userIntegralLogs.isEmpty()) {
			return;
		}
		StringBuffer excelName = new StringBuffer("用户积分流水");
		XSSFWorkbook wb = new XSSFWorkbook();
		// 创建单元格，并设置值表头 设置表头居中
		XSSFCellStyle style = wb.createCellStyle();
		// 创建一个居中格式
		style.setAlignment(HorizontalAlignment.CENTER);
		XSSFDataFormat format = wb.createDataFormat();
		// 表头  
		LinkedHashMap<String, String> commonPrefixMap = new LinkedHashMap<>();
		commonPrefixMap.put("cts", "操作时间");
		commonPrefixMap.put("uid", "uid");
		commonPrefixMap.put("uname", "昵称");
		commonPrefixMap.put("realName", "姓名");
		commonPrefixMap.put("sname", "学校");
		commonPrefixMap.put("rleNames", "角色");
		commonPrefixMap.put("itName", "变动类型");
		commonPrefixMap.put("increaseIntegral", "变动积分");
		commonPrefixMap.put("comment", "内容");
		commonPrefixMap.put("creator", "操作人ID");
		
		XSSFSheet sheet = wb.createSheet("用户积分流水");
		ExportExcelUtil.fillSheet(sheet, userIntegralLogs, commonPrefixMap, style, format);
		// 导出excel
		ExportExcelUtil.export(excelName.toString(), wb, response);
	}
	/**
	 * 通过excel批量增减积分
	 * @param file
	 * @return
	 * @throws Exception 
	 * @throws IOException 
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = ADreamServiceException.class, isolation = Isolation.DEFAULT)
	public ResultModel<?> importUpdateUserIntegrals(MultipartFile file) throws Exception {
		List<ExcelHead> excelHeads = new ArrayList<ExcelHead>();
		//获取excel的特定单元格列数据
		ExcelHead excelHead1 = new ExcelHead("uid", "uid");
		ExcelHead excelHead2 = new ExcelHead("增减类型", "type");
		ExcelHead excelHead3 = new ExcelHead("积分数", "integral");
		ExcelHead excelHead4 = new ExcelHead("变动类型", "itName");
		ExcelHead excelHead5 = new ExcelHead("内容", "comment");
		excelHeads.add(excelHead1);
		excelHeads.add(excelHead2);
		excelHeads.add(excelHead3);
		excelHeads.add(excelHead4);
		excelHeads.add(excelHead5);
		List<ImportUserIntegral> importUserIntegrals = ImportExcelUtil.readExcelToEntity(ImportUserIntegral.class, file.getInputStream(), file.getOriginalFilename(), excelHeads);
		if(Utils.isEmptyCollection(importUserIntegrals)) {
			logger.warn("批量增减积分失败,相关数据不存在:(");
			return new ResultModel<String>(ResultModel.ERR_PARAM, "更新失败,数据不存在", null);
		}
		//循环遍历检测下数据
		int importUserIntegralsSize = importUserIntegrals.size();
		for (int i = 0; i < importUserIntegralsSize; i++) {
			ImportUserIntegral importUserIntegral = importUserIntegrals.get(i);
			//判断uid
			if(StringUtils.isEmpty(importUserIntegral.getUid())) {
				logger.warn("批量增减积分失败,uid为空:(");
				return new ResultModel<String>(ResultModel.ERR_PARAM, "更新失败,uid数据为空", null);
			}
			//判断操作类型
			if(!Constant.INTEGRAL_OPERATE_TYPE_DECREASE.equals(importUserIntegral.getType())
					&& !Constant.INTEGRAL_OPERATE_TYPE_INCREASE.equals(importUserIntegral.getType())) {
				logger.warn("批量增减积分失败,操作类型错误,uid:" + importUserIntegral.getUid());
				return new ResultModel<String>(ResultModel.ERR_PARAM, "更新失败,数据uid:" + importUserIntegral.getUid() + "的增减类型有误", null);
			}
			//判断变动类型
			if(StringUtils.isEmpty(importUserIntegral.getItName())) {
				logger.warn("批量增减积分失败,变动类型错误,uid:" + importUserIntegral.getUid());
				return new ResultModel<String>(ResultModel.ERR_PARAM, "更新失败,数据uid:" + importUserIntegral.getUid() + "的变动类型有误", null);
			}
			//判断内容字段
			if(StringUtils.isEmpty(importUserIntegral.getComment())) {
				logger.warn("批量增减积分失败,内容为空,数据uid:" + importUserIntegral.getUid());
				return new ResultModel<String>(ResultModel.ERR_PARAM, "更新失败,数据uid:" + importUserIntegral.getUid() + "的内容为空", null);
			}
			//判断内容字段长度
			if(importUserIntegral.getComment().length() > Constant.LONG_DATA_LENGTH) {
				logger.warn("更新用户积分数失败,内容太长,数据uid:" + importUserIntegral.getUid());
				return new ResultModel<String>(ResultModel.WARN_DATA_LENGTH, "更新失败,数据uid:" + importUserIntegral.getUid() + "的内容太长,请精简", null);
			}
		}
		//进行积分数更新
		for (int i = 0; i < importUserIntegralsSize; i++) {
			ImportUserIntegral importUserIntegral = importUserIntegrals.get(i);
			UserEntity user = userDao.queryUserByDrAndUid(Constant.ONE,importUserIntegral.getUid());
			if(user == null) {
				logger.warn("用户积分更新失败,用户不存在:(");
				throw new ADreamServiceException("更新失败,数据uid:" + importUserIntegral.getUid() + "的用户不存在");
			}
			//查询积分变动类型
			IntegralTypeEntity integralType = integralTypeDao.queryIntegralTypeByNameAndDr(importUserIntegral.getItName(), Constant.ONE);
			if(integralType == null) {
				logger.warn("用户更新失败,数据uid:" + importUserIntegral.getUid() + "的变动类型不存在:(");
				throw new ADreamServiceException("更新失败,数据uid:" + importUserIntegral.getUid() + "的变动类型不存在");
			}
			int oldIntegral = user.getIntegral() == null ? 0 : user.getIntegral();
			int increaseInteral = Constant.INTEGRAL_OPERATE_TYPE_INCREASE.equals(importUserIntegral.getType()) 
					? importUserIntegral.getIntegral() : (-1) * importUserIntegral.getIntegral();
			String operator = session.getAttribute("uid") == null ? user.getUid() : (String) session.getAttribute("uid");
			user.setModifier(operator);
			user.setIntegral(oldIntegral + increaseInteral);
			int result = userDao.updateUserIntegralByUid(user);
			if(result == Constant.ZERO) {
				logger.warn("用户积分更新失败,数据库错误:(");
				throw new ADreamServiceException("系统错误101a,请联系系统管理员");
			}
			//添加一条积分历史变更数据
			IntegralHistoryEntity integralHistory = new IntegralHistoryEntity();
			integralHistory.setIhid(IdGenerator.getGuid());
			integralHistory.setUid(importUserIntegral.getUid());
			integralHistory.setOldIntegral(oldIntegral);
			integralHistory.setNewIntegral(oldIntegral + increaseInteral);
			integralHistory.setIncreaseIntegral(increaseInteral);
			integralHistory.setItid(integralType.getItid());
			integralHistory.setComment(importUserIntegral.getComment());
			integralHistory.setCreator(operator);
			integralHistory.setModifier(operator);
			integralHistory.setDr(Constant.ONE);
			int addIntegralHistoryResult = integralHistoryDao.addIntegralHistory(integralHistory);
			if(addIntegralHistoryResult == Constant.ZERO) {
				logger.warn("积分明细新增失败,数据库错误:(");
				throw new ADreamServiceException("系统错误102a,请联系系统管理员");
			}
		}
		return new ResultModel<String>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, null);
	}

	public PageInfo<Map<String, Object>> getIntegralHistory(String uid, int pageNo, int pageSize) {
		if(StringUtils.isEmpty(uid)) {
			return new PageInfo<>(new ArrayList<Map<String, Object>>());
		}
		PageHelper.startPage(pageNo, pageSize);
		List<Map<String, Object>> rlt = integralHistoryDao.getIntegralHistoryByUid(uid);
		// 封装Page对象 每页显示10条记录
		PageInfo<Map<String, Object>> page = new PageInfo<>(rlt, Constant.TEN);
		return page;
	}

	public List<Map<String, Object>> getPhonesByUids(List<String> uids) {
		if(uids == null || uids.isEmpty()) {
			return null;
		}
		return userDao.getPhonesByUids(uids);
	}

	public Integer queryMyIntegralByUid(String uid) {
		if(StringUtils.isEmpty(uid)) {
			return null;
		}
		return userDao.getUserIntegralByUid(uid);
	}
	
	public Integer queryMaxIntegralByUid(String uid) {
		if(StringUtils.isEmpty(uid)) {
			return null;
		}
		return userDao.queryMaxIntegralByUid(uid);
	}

	public List<Map<String, Object>> getUidsByPhones(List<String> phones) {
		if(phones == null || phones.isEmpty()) {
			return null;
		}
		return userDao.getUidsByPhones(phones);
	}

	public ResultModel<?> frontUnBindWxUnionid(String uid) {
		UserEntity user = userDao.queryUserByUid(uid);
		if (user != null) {
			user.setUnionid(null);
			userDao.updateUser(user);
		}
		return new ResultModel<String>(ResultModel.SUCCESS, ResultModel.SUCCESS_MSG, null);
	}
	
	/**
	 * 根据权限点&删除标志	查询用户uid列表
	 * @param resId
	 * @param dr
	 * @return
	 */
	public ResultModel<?> getUidsByResIdAndDr(String resId, int dr) {
		List<String> uids = userDao.queryUidsByResIdAndDr(resId, dr);
		if(Utils.isEmptyCollection(uids)) {
			return new ResultModel<List<String>>(ResultModel.NOT_FOUND_OBJECT, "未查询到相应用户", null);
		}
		return new ResultModel<List<String>>(ResultModel.SUCCESS, "查询成功", uids);
	}

	public List<String> getUserRoleIdsByUid(String uid) {
		if(StringUtils.isEmpty(uid)) {
			return null;
		}
		return userDao.getUserRoleIdsByUid(uid);
	}

	public ResultModel<?> getContactInfByUid(String uid,String appid) {
		Map<String,String> result= new HashMap<>(3);
		UserEntity u = userDao.queryUserByUid(uid);
		result.put("email", u.getEmail());
		result.put("phone", u.getPhone());
		if(StringUtil.isNotEmpty(appid)) {
			String openid = userDao.queryOpenIdByUidOpenid(uid,appid);
			if(StringUtil.isNotEmpty(appid)) {
				result.put("openid", openid);
			}
		}
		return new ResultModel<>(ResultModel.SUCCESS, "查询成功", result);
	}
}